<template>
  <div class="wheel-container">
    <div :id="'wheel-' + uid" class="wheel"></div>
  </div>
</template>

<script>
import * as d3 from "d3";
import { ref } from "vue";
export default {
  name: "WheelOfFortune",
  props: {
    size: {
      type: Number,
      default: 350,
      validator: (value) => value >= 200 && value <= 1600,
    },
    showImg: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      rotation: 0,
      oldrotation: 0,
      picked: 1000,
      uid: Math.random().toString(36).substring(2, 9),
      data: [
        {
          label: "18%折扣",
          value: 1,
          img: "https://picsum.photos/100/100?random=1",
        },
        {
          label: "下次好运",
          value: 2,
          img: "https://picsum.photos/100/100?random=2",
        },
        {
          label: "10%折扣",
          value: 3,
          img: "https://picsum.photos/100/100?random=3",
        },
        {
          label: "免费面膜",
          value: 4,
          img: "https://picsum.photos/100/100?random=4",
        },
        {
          label: "15%折扣",
          value: 5,
          img: "https://picsum.photos/100/100?random=5",
        },
        {
          label: "免运费",
          value: 6,
          img: "https://picsum.photos/100/100?random=6",
        },
        {
          label: "10%折扣",
          value: 7,
          selected: true,
          img: "https://picsum.photos/100/100?random=7",
        },
        {
          label: "15%折扣",
          value: 1,
          img: "https://picsum.photos/100/100?random=8",
        },
        {
          label: "下次好运",
          value: 2,
          img: "https://picsum.photos/100/100?random=9",
        },
      ],
    };
  },
  mounted() {
    this.initWheel();
  },
  watch: {
    size(newSize) {
      d3.select(this.$el).select("svg").remove();
      this.initWheel();
    },
    showImg(newSize) {
      d3.select(this.$el).select("svg").remove();
      this.initWheel();
    },
  },
  methods: {
    initWheel() {
      const elementId = "wheel-" + this.uid;
      const size = this.size;

      const padding = { top: 0, right: 0, bottom: 0, left: 0 };
      const w = size - padding.left - padding.right;
      const h = size - padding.top - padding.bottom;
      const r = Math.min(w, h) / 2;

      const color = d3.scaleOrdinal(d3.schemeCategory10);

      const svg = d3
        .select(`#${elementId}`)
        .append("svg")
        .attr("width", w + padding.left + padding.right)
        .attr("height", h + padding.top + padding.bottom);

      const container = svg
        .append("g")
        .attr("class", "chartholder")
        .attr(
          "transform",
          `translate(${w / 2 + padding.left}, ${h / 2 + padding.top})`
        );

      // 添加初始旋转-90度，使0点位置在正上方
      const vis = container.append("g");

      const pie = d3
        .pie()
        .sort(null)
        .value(() => 1);

      const pieData = pie(this.data);

      const arc = d3
        .arc()
        .innerRadius(0)
        .outerRadius(r - 1);

      const arcs = vis
        .selectAll("g.slice")
        .data(pieData)
        .enter()
        .append("g")
        .attr("class", "slice");

      arcs
        .append("path")
        .attr("fill", (d, i) => color(i))
        .style("stroke", "#fff")
        .style("stroke-width", "2px")
        .attr("d", (d) => arc(d));

      const fontSize = Math.max(10, size / 25);
      const textStyle = ref([(40 / 350) * this.size, "end"]);
      const imgSize = (42 / 350) * this.size;
      if (this.showImg) {
        textStyle.value[0] = (30 / 350) * this.size;
        textStyle.value[1] = "middle";
        // 定义一个裁剪路径（整个svg只定义一个，因为大小都一样）
        const clipId = `clip-${this.uid}`;
        svg
          .append("defs")
          .append("clipPath")
          .attr("id", clipId)
          .append("rect")
          .attr("rx", imgSize / 7) // 圆角半径
          .attr("ry", imgSize / 7)
          .attr("width", imgSize)
          .attr("height", imgSize);

        // 创建图片的组
        const imgs = arcs.append("g").attr("transform", (d) => {
          const midAngle = (d.startAngle + d.endAngle) / 2;
          let degrees = (midAngle * 180) / Math.PI;
          const radius = r - (70 / 350) * this.size;
          const x = Math.sin(midAngle) * radius;
          const y = -Math.cos(midAngle) * radius;
          return `translate(${x}, ${y}) rotate(${degrees})`;
        });

        // 在组内添加图片
        imgs
          .append("image")
          .attr("xlink:href", (d, i) => this.data[i].img)
          .attr("width", imgSize)
          .attr("height", imgSize)
          .attr("transform", `translate(-${imgSize / 2}, -${imgSize / 2})`)
          .attr("clip-path", `url(#${clipId})`); // 应用裁剪

        // 在组内添加边框（圆角矩形）
        imgs
          .append("rect")
          .attr("x", -imgSize / 2)
          .attr("y", -imgSize / 2)
          .attr("width", imgSize)
          .attr("height", imgSize)
          .attr("rx", imgSize / 7)
          .attr("ry", imgSize / 7)
          .attr("fill", "none")
          .attr("stroke", "rgba(0,0,0,0.1)")
          .attr("stroke-width", (1 / 350) * this.size);

        // 修正文本定位逻辑（基于正上方0度）
      }
      arcs
        .append("text")
        .attr("transform", (d) => {
          const midAngle = (d.startAngle + d.endAngle) / 2;
          // 计算相对于正上方的角度（弧度转角度）
          let degrees = (midAngle * 180) / Math.PI - 90;
          if (this.showImg) {
            degrees = degrees + 90;
          }
          //   const degrees = 0;
          // 调整文本位置（向外移动）
          const radius = r - textStyle.value[0];
          // 计算坐标位置（基于正上方坐标系）
          const x = Math.sin(midAngle) * radius;
          const y = -Math.cos(midAngle) * radius;
          return `translate(${x},${y}) rotate(${degrees})`;
        })
        .attr("text-anchor", textStyle.value[1]) // 居中对齐
        .attr("dominant-baseline", "middle") // 垂直居中
        .attr("fill", "#fff")
        .attr("font-weight", "bold")
        .attr("font-size", `${fontSize}px`)
        .text((d, i) => this.data[i].label);
      // 添加指针（固定在正上方）
      container
        .append("path")
        .attr("d", `M-${r * 0.15},0L0,${r * 0.05}L0,-${r * 0.05}Z`)
        .attr("fill", "#ff3333")
        .attr("transform", `translate(0, ${-r * 0.98}) rotate(270)`)
        .attr("stroke", "#800000")
        .attr("stroke-width", "1px");

      // 中心按钮（保持不变）
      const centerSize = r * 0.15;
      container
        .append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("r", centerSize)
        .style("fill", "#fff3c0")
        .style("cursor", "pointer");

      container
        .append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("r", centerSize * 0.9)
        .style("fill", "#efad60")
        .style("cursor", "pointer");

      container
        .append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("r", centerSize * 0.8)
        .style("fill", "#eb9b4e")
        .style("cursor", "pointer");

      container
        .append("text")
        .attr("x", 0)
        .attr("y", 0)
        .attr("text-anchor", "middle") // 水平居中
        .attr("dominant-baseline", "middle") // 垂直居中
        .attr("fill", "#fff")
        .attr("font-weight", "bold")
        .attr("font-size", `${centerSize * 0.7}px`)
        .text("GO")
        .style("cursor", "pointer");

      container.on("click", this.spin);
    },
    spin() {
      const selectedIndex = this.data.findIndex((item) => item.selected) || 0;
      const segmentAngle = 360 / this.data.length;

      // 计算目标角度（基于正上方坐标系）
      const targetRotation = selectedIndex * segmentAngle + segmentAngle / 2;

      // 计算需要旋转的总角度（2圈 + 目标角度）
      const fullRotations = 360 * 4;
      this.rotation = fullRotations + targetRotation;
      this.picked = selectedIndex;

      const vis = d3.select(this.$el).select(".chartholder > g");

      vis
        .transition()
        .duration(4000)
        .attrTween("transform", () => this.rotTween())
        .on("end", () => {
          this.oldrotation = this.rotation % 360;
          this.$emit("spin-end", {
            result: this.data[this.picked],
            index: this.picked,
          });
        });
    },
    reset() {
      this.oldrotation = 0;
      d3.select(this.$el)
        .select(".chartholder > g")
        .attr("transform", "rotate(-90)");
    },
    rotTween() {
      const i = d3.interpolate(this.oldrotation, this.rotation);
      return (t) => `rotate(${i(t)})`;
    },
  },
};
</script>

<style>
/* 样式保持不变 */
.wheel-container {
  position: relative;
  margin: 0 auto;
}

.wheel {
  display: inline-block;
  overflow: visible;
}

.wheel text {
  /* font-size: 14px; */
  pointer-events: none;
  font-family: Arial, sans-serif;
  fill: #fff;
}

.wheel .slice path {
  transition: opacity 0.3s ease;
}

.wheel .slice path:hover {
  opacity: 0.9;
}
</style>